Zwiększanie wydajności
==================

Na wydajność aplikacji sieciowych ma wpływ wiele czynników. Dostęp do baz danych,
operacje na plikach, przepustowość sieci, wszystkie z nich potencjalnie są tymi 
czynnikami. Yii stara się w każdym aspekcie redukować wpływy na wydajność 
powodowane przez framework. Mimo to, jest wiele miejsc w aplikacji użytkownika, 
które mogą zostać poprawione by zwiększyć wydajność.

Włączanie rozszerzenia APC
----------------------

Włączenie [rozszerzenia PHP APC](http://www.php.net/manual/en/book.apc.php) jest 
prawdopodobnie najłatwiejszym sposobem zwiększenia całkowitej wydajności aplikacji.
Rozszerzenie to buforuje oraz optymalizuje pośredni kod PHP unikając w ten sposób,
czasu poświęconego na parsowanie skryptu PHP wraz z każdym nadchodzącym żądaniem.

Wyłączanie trybu debugowania
--------------------

Wyłączenie trybu debugowania jest kolejnym prostym sposobem na poprawienie wydajności
aplikacji. Aplikacja Yii działa w trybie debugowania, jeśli stała `YII_DEBUG` 
jest zdefiniowana jako wartość true. Tryb debugowania jest użyteczny w trakcie
fazy tworzenia aplikacji, jednakże wpływa on na wydajność, ponieważ część
komponentów powoduje dodatkowe obciążenia. Na przykład, logger komunikatów
może zapisywać dodatkowe informacje dla każdego logowanego komunikatu. 

Używanie `yiilite.php`
-------------------

Jeśli rozszerzenie PHP [APC](http://www.php.net/manual/en/book.apc.php) jest włączone,
możemy zastąpić `yii.php` innym plikiem inicjalizującym (ang. bootstrap) `yiilite.php` 
aby później zwiększyć wydajność aplikacji opartych o Yii.


Plik `yiilite.php` dostarczany jest wraz z każdym wydaniem Yii. Jest on rezultatem 
połączenia pewnych często używanych w Yii plików klas. Zarówno komentarze oraz 
wyrażenia śledzenia (trace) są usuwane z tego połączonego pliku. Dlatego też używanie `yiilite.php` 
spowoduje redukcję ilości plików dołączanych oraz uniknięcie wywołań wyrażeń śledzenia (trace).

Zauważ, że używanie `yiilite.php` bez APC, może zmniejszyć wydajność ponieważ `yiilite.php`
zawiera część klas, które niekoniecznie używane są w każdym żądaniu, przez co 
zwiększają one czas parsowania. Zauważono również, że używanie `yiilite.php`
jest wolniejsze dla pewnych konfiguracji serwera, nawet jeśli włączone jest APC.
Najlepszym sposobem rozstrzygnięcia czy używać `yiilite.php` czy też nie 
jest uruchomienie benchmarku używającego załączone do Yii demo `hello world`.

Używanie technik buforowania
------------------------

Tak jak to opisano w sekcji [buforowanie](/doc/guide/caching.overview), Yii dostarcza
kilka rozwiązań związanych z buforowaniem, które mogą zwiększyć w znacznym stopniu wydajność 
aplikacji sieciowej. Jeśli generowanie pewnych danych zabiera wiele czasu, możemy
użyć techniki [buforowania danych](/doc/guide/caching.data) w celu zredukowania 
częstotliwości generowania danych; jeśli część strony pozostaje relatywnie statyczna
możemy użyć techniki [buforowania fragmentarycznego](/doc/guide/caching.fragment)
w celu zredukowania częstotliwości renderowania tego fragmentu; jeżeli cała strona 
pozostaje relatywnie statyczna, możemy użyć techniki [buforowania strony](/doc/guide/caching.page) 
w celu zredukowania kosztu generowania całej strony. 

Jeśli aplikacja używa [rekordu aktywnego](/doc/guide/database.ar) powinniśmy włączyć
buforowanie schematu bazy danych by zmniejszyć czas parsowania schematu bazy danych.
Można to uczynić poprzez skonfigurowanie właściwości [CDbConnection::schemaCachingDuration]
nadając jej wartość większą niż 0.


Poza wymienionymi technikami buforowania na poziomie aplikacji, możemy również skorzystać
z rozwiązań na poziomie serwera w celu poprawienia wydajności aplikacji. 
[Buforowanie APC](/doc/guide/topics.performance#enabling-apc-extension), które wcześniej opisaliśmy
bezsprzecznie należy do tej kategorii. Wyróżnia się tutaj inne techniki, między innymi takie jak 
[Zend Optimizer](http://www.zend.com/en/products/guard/zend-optimizer), [eAccelerator](http://eaccelerator.net/),
[Squid](http://www.squid-cache.org/).

Optymalizacja bazy danych
---------------------

Pobieranie danych z bazy danych jest często główną przyczyną wąskich gardeł wydajnościowych 
w aplikacjach internetowych. Chociaż używanie buforowanie może złagodzić zakłócenie wydajności
nie rozwiązuje one w pełni problemu. Jeśli baza danych zawiera ogromne ilości danych 
a dane zbuforowane są niepoprawne, pobieranie dużej ilości danych może być nadmiernie
kosztowne bez właściwego zaprojektowania bazy danych oraz zapytań. 

Twórz indeksy w bazach danych mądrze. Indeksowanie może uczynić zapytania z `SELECT`
dużo szybszymi, ale może spowolnić zapytania `INSERT`, `UPDATE` czy też `DELETE`.

W przypadku złożonych zapytań rekomenduje się utworzenie w bazie danej widoku dla nich
zamiast wywoływania zapytań z poziomu kodu PHP i proszenia DBMS o każdorazowe (powtarzające się) ich parsowanie.

Nie nadużywaj [rekordu aktywnego](/doc/guide/database.ar). Chociaż [rekord aktywny](/doc/guide/database.ar) 
jest dobry w modelowaniu danych w stylu obiektowym (OOP), faktycznie obniża on 
wydajność ze względu na to, iż potrzebuje utworzyć jeden lub więcej obiektów
do reprezentowania każdego wiersza wyniku zapytania. Dla aplikacji intensywnie używających
danych używanie [DAO](/doc/guide/database.dao) lub też API bazy danych na niższym poziomie
może być lepszym wyborem.

Nie mniej ważnym jest używanie `LIMIT` w zapytaniach `SELECT`. Pozwala to unikania 
pobierania przytłaczającej ilości danych z bazy danych oraz wyczerpywania pamięci 
przydzielonej dla PHP.

Minimalizacja rozmiaru plików skryptów
-----------------------

Złożone strony często potrzebują dołączać wiele zewnętrznych plików zawierających JavaScript 
oraz CSS. Ponieważ każdy z plików spowoduje dodatkowy ruch do i z serwera, powinniśmy zminimalizować
ilość plików skryptów poprzez połączenie ich w mniejszą ilość. Powinniśmy również rozważyć 
zmniejszenie rozmiaru każdego z plików skryptu w celu zmniejszenia czasu przesyłu w sieci. 
Istnieje wiele narzędzi, które pomogą w tych dwóch aspektach.

Dla stron generowanych przez Yii istnieje możliwość, że znajdują się tam pewne pliki
skryptów generowane przez komponenty, których nie chcemy modyfikować 
(np. rdzenne komponenty Yii, komponenty stron trzecich). W celu minimalizacji tych plików 
skryptów, potrzebujemy wykonać dwa kroki.

Najpierw deklarujemy, które pliki chcemy zminimalizować poprzez skonfigurowanie właściwości  
[scriptMap|CClientScript::scriptMap] komponentu aplikacji [clientScript|CWebApplication::clientScript].
Możemy to zrobić zarówno w konfiguracji aplikacji jak i w kodzie. Na przykład:


~~~
[php]
$cs=Yii::app()->clientScript;
$cs->scriptMap=array(
	'jquery.js'=>'/js/all.js',
	'jquery.ajaxqueue.js'=>'/js/all.js',
	'jquery.metadata.js'=>'/js/all.js',
	......
);
~~~

To co wykonuje powyższy kod, to mapowanie tych plików JavaScript do adresu URL `/js/all.js`. 
Jeśli któryś z tych plików JavaScript będzie musiał być dołączony przez, któryś 
z komponentów, Yii załączy (raz) URL zamiast kolejnego załączania poszczególnych plików skryptu.

Po drugie, potrzebujemy użyć pewnych narzędzi do połączenia (i prawdopodobnie skompresowania) 
plików JavaScript w jeden oraz zapisanie go jako `js/all.js`.

Ten sam trik ma zastosowanie dla plików CSS.

Możemy również poprawić prędkość ładowania strony przy pomocy [Google AJAX Libraries API](http://code.google.com/apis/ajaxlibs/). 
Na przykład, możemy załączyć plik `jquery.js` z serwera Google zamiast z naszego własnego. 
Aby to zrobić, najpierw konfigurujemy właściwość `scriptMap` w następujący sposób,

~~~
[php]
$cs=Yii::app()->clientScript;
$cs->scriptMap=array(
	'jquery.js'=>false,
	'jquery.ajaxqueue.js'=>false,
	'jquery.metadata.js'=>false,
	......
);
~~~

Poprzez zmapowanie tych plików skryptu do wartości false, powstrzymujemy Yii od generowania kodu 
potrzebnego do załączenia tych plików. W zamian, piszemy następujący kod na naszej stronie 
aby bezpośrednio dołączyć pliki skryptów ze strony Google:

~~~
[php]
<head>
<?php echo CGoogleApi::init(); ?>

<?php echo CHtml::script(
	CGoogleApi::load('jquery','1.3.2') . "\n" .
	CGoogleApi::load('jquery.ajaxqueue.js') . "\n" .
	CGoogleApi::load('jquery.metadata.js')
); ?>
......
</head>
~~~

<div class="revision">$Id: topics.performance.txt 2890 2011-01-18 15:58:34Z qiang.xue $</div>